package com.woniuxy.config;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.woniuxy.handler.*;
import com.woniuxy.service.SecurityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;

import javax.annotation.Resource;

/**
 * 自定义账号和密码
 * 1、用框架提供好的方法，把账号和密码写入
 * 2、用数据库中的账号和密码登录
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    SecurityService securityService;

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    @Autowired
    private JWThandler jWThandler;

    @Autowired
    private ChangeDbHandler changeDbHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //用框架提供好的方法，把账号和密码写入
        //密码只能加密后放入
       /* PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String pw = passwordEncoder.encode("123");
        auth.inMemoryAuthentication().withUser("tom").password(pw).roles("");*/

        auth.userDetailsService(securityService);
    }

    protected void configure(HttpSecurity http) throws Exception {
          //自定义表单
        http.formLogin()//告诉框架用自定义表单
                //.loginPage("/login.html")//指定自定义表单位置
                .loginProcessingUrl("/dologin")//指定登录请求的url
                .successHandler(loginSuccessHandler)//登录成功后的处理器
                .failureHandler(new LoginFailHandler())//登录失败后的处理器
                .permitAll();//登录页面不需要认证，放行面两个请求

        http.csrf().disable().authorizeRequests().antMatchers("hospital/queryHospitalMetas","hospital/changeDB/*").permitAll();

        http.exceptionHandling()
                        .authenticationEntryPoint(new NoLoginHandler())//未登录的处理器
                        .accessDeniedHandler(new NoAuthHandler());//注册无权限的处理器


                 http.authorizeRequests()
                         //对接口权限控制
                         //登录用户只有 querySal这个权限code码才能访问该接口
//                         .antMatchers("/sal").hasAuthority("querySal")
//                         //可以给接口配置多个能访问的权限code码,只要有其中一个就能访问
//                         .antMatchers("/queryUser").hasAnyAuthority("queryInfo","queryUser")
//                         .antMatchers("/hello").hasRole("queryInfo")//拼前缀 RP;E_queryInfo
//                        // .antMatchers("/hello").hasAnyRole("queryInfo","queryUser")//拼前缀 RP;E_queryInfo,RP;E_queryUser

                         .antMatchers("/home","/drug/upload","/alipay/pay","/alipay/num","/alipay/drug","/WebSocketHandler/**").permitAll()//配置接口免登录访问

                         .antMatchers("/home","/drug/upload","/alipay/pay","/alipay/num","/alipay/drug","/alipay/recharge").permitAll()//配置接口免登录访问

                         .anyRequest().authenticated();//所有请求都需要认证，都被拦截

        http.csrf().disable();//因为没有自定义表单没有做预防csrf(跨站脚本攻击)攻击，所以要禁用

        //把jwt过滤器加到框架过滤器链中
        //参数1:自己过滤器,参数2:目标过滤器
        http.addFilterAfter(jWThandler, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(changeDbHandler, UsernamePasswordAuthenticationFilter.class);

        //jwt作为凭证要禁用掉session
//        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        //增加退出操作
        http.logout()
                .logoutUrl("/logouts")
                .logoutSuccessUrl("/").permitAll();

    }
    //加密方式放入容器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //忽略websocket拦截
    @Override
    public void configure(WebSecurity webSecurity) {
        webSecurity.ignoring().antMatchers(
                "/WebSocketHandler/**"
        );
    }



}
